#include "./common/abc_common.cpp"
#include "./common/function_utils.cpp"

using CB = std::function<void(AbckitCoreFunction *)>;

std::shared_ptr<AbcFile> g_abcFile = std::make_shared<AbcFile>();
void EnumerateAllMethodsInModule(
    AbckitFile *file, std::function<void(AbckitCoreNamespace *)> &cbNamespace,
    std::function<void(AbckitCoreClass *, std::shared_ptr<AbcModule>)> &cbClass,
    std::function<void(AbckitCoreFunction *)> &cbFunc,
    const std::shared_ptr<ProcessedScanConfig> &processedScan)
{
    std::function<void(AbckitCoreModule *)> cbModule = [&](AbckitCoreModule *m)
    {
        auto abcModule = std::make_shared<AbcModule>();
        abcModule->module = m;
        AbckitString *moduleNameStr = g_implI->moduleGetName(m);
        if (moduleNameStr != nullptr)
        {
            std::string moduleName = g_implI->abckitStringToString(moduleNameStr);
            if (moduleName.find_first_of('@') == 0)
            {
                abcModule->entityInfo.moduleName = moduleName;
                return;
            }
            else
            {
                size_t firstAmpersand = moduleName.find('&');
                size_t firstSlash = moduleName.find('/', firstAmpersand + 1);
                abcModule->entityInfo.moduleName = moduleName.substr(firstAmpersand + 1, firstSlash - firstAmpersand - 1);
                size_t secondAmpersand = moduleName.find('&', firstAmpersand + 1);
                if (firstAmpersand != std::string::npos && secondAmpersand != std::string::npos)
                {
                    abcModule->entityInfo.path = moduleName.substr(firstSlash + 1, secondAmpersand - firstSlash - 1);
                }
            }
        }

        if (!ShouldProcessModule(abcModule->entityInfo.moduleName, processedScan))
        {
            return; // 按配置过滤模块，则直接返回
        }

        if (!ShouldProcessPath(abcModule->entityInfo.path, processedScan))
        {
            return; // 路径不匹配，直接返回
        }

        g_implI->moduleEnumerateNamespaces(m, &cbNamespace, [](AbckitCoreNamespace *n, void *cb)
                                           {
            (*reinterpret_cast<std::function<void(AbckitCoreNamespace*)>*>(cb))(n);
            return true; });

        auto cbAndModule = std::make_pair(&cbClass, &abcModule);
        g_implI->moduleEnumerateClasses(m, &cbAndModule, [](AbckitCoreClass *c, void *cb)
                                        {
            auto* cbAndModule = static_cast<
                std::pair<std::function<void(AbckitCoreClass*, std::shared_ptr<AbcModule>)>*,
                          std::shared_ptr<AbcModule>*>*>(cb);
            (*cbAndModule->first)(c, *cbAndModule->second);
            return true; });

        auto cbAndModuleForTopLevelFunc = std::make_pair(&cbFunc, &abcModule);
        g_implI->moduleEnumerateTopLevelFunctions(
            m, &cbAndModuleForTopLevelFunc, [](AbckitCoreFunction *m, void *cb)
            {
                auto* cbAndModule = static_cast<std::pair<std::function<void(AbckitCoreFunction*)>*,
                                                          std::shared_ptr<AbcModule>*>*>(cb);
                (*cbAndModule->first)(m);
                auto module = *(cbAndModule->second);
                // 处理顶层函数与模块的关系
                auto abcFunc = std::make_shared<AbcFunction>();
                FillFunctionInfo(abcFunc.get(), m, nullptr, module.get());
                module->funcList.push_back(abcFunc);
                return true; });
        // // 匿名函数
        auto cbAndModuleForAnonymousFunc = std::make_pair(&cbFunc, &abcModule);
        g_implI->moduleEnumerateAnonymousFunctions(
            m, &cbAndModuleForAnonymousFunc, [](AbckitCoreFunction *m, void *cb)
            {
                auto* cbAndModule = static_cast<std::pair<std::function<void(AbckitCoreFunction*)>*,
                                                          std::shared_ptr<AbcModule>*>*>(cb);
                (*cbAndModule->first)(m);
                auto module = *(cbAndModule->second);
                // 处理匿名函数与模块的关系
                auto abcFunc = std::make_shared<AbcFunction>();
                FillFunctionInfo(abcFunc.get(), m, nullptr, module.get());
                module->funcList.push_back(abcFunc);
                return true; });
        g_abcFile->moduleList.push_back(abcModule);
    };

    g_abcFile->file = file;
    g_implI->fileEnumerateModules(file, &cbModule, [](AbckitCoreModule *m, void *cb)
                                  {
        (*reinterpret_cast<std::function<void(AbckitCoreModule*)>*>(cb))(m);
        return true; });
}

void EnumerateAllMethods(AbckitFile *file, const CB &cbUserFunc, const std::shared_ptr<ProcessedScanConfig> &processedScan)
{
    CB cbFunc = [&, processedScan](AbckitCoreFunction *f)
    {
        cbUserFunc(f);
        // auto abcFunc = std::make_shared<AbcFunction>();
        // FillFunctionInfo(abcFunc.get(), f, abcClass.get(), nullptr);
        // if (ShouldProcessMethod(abcFunc->funcName, processedScan))
        // {
        //     std::cout << "找到函数: " << abcFunc->funcName << std::endl;
        //     abcClass->funcList.push_back(abcFunc);
        // }
        g_implI->functionEnumerateNestedFunctions(f, &cbFunc, [](AbckitCoreFunction *m, void *cb)
                                                  {
            (*reinterpret_cast<CB*>(cb))(m);
            return true; });
    };

    std::function<void(AbckitCoreClass *, std::shared_ptr<AbcModule>)> cbClass =
        [&, processedScan](AbckitCoreClass *c, std::shared_ptr<AbcModule> module)
    {
        auto abcClass = std::make_shared<AbcClass>();
        abcClass->cls = c;
        AbckitString *classNameStr = g_implI->classGetName(c);
        abcClass->entityInfo.className = g_implI->abckitStringToString(classNameStr);
        std::cout << "找到类: " << abcClass->entityInfo.className << std::endl;
        if (!ShouldProcessClass(abcClass->entityInfo.className, processedScan))
        {
            std::cout << "跳过类: " << abcClass->entityInfo.className << std::endl;
            return; // 类名不在配置列表中，直接返回，不收集该类的方法
        }
        AbckitCoreNamespace *namespaceName = g_implI->classGetParentNamespace(c);
        if (namespaceName != nullptr)
        {
            AbckitString *namespaceNameStr = g_implI->namespaceGetName(namespaceName);
            abcClass->entityInfo.parentNamespaceName =
                g_implI->abckitStringToString(namespaceNameStr);
        }
        abcClass->entityInfo.moduleName = module->entityInfo.moduleName;
        abcClass->entityInfo.path = module->entityInfo.path;

        auto funcAndClass = std::make_tuple(&cbFunc, &abcClass, &processedScan);
        g_implI->classEnumerateMethods(c, &funcAndClass, [](AbckitCoreFunction *m, void *cb)
                                       {
                // 可选：跳过构造函数
                if (g_implI->functionIsCtor(m))
                {
                    return true; 
                }
                auto *funcAndClass = static_cast<std::tuple<CB *, std::shared_ptr<AbcClass> *, std::shared_ptr<ProcessedScanConfig> *> *>(cb);
                auto *cbFunc = std::get<0>(*funcAndClass);
                auto abcClass = *(std::get<1>(*funcAndClass));
                auto processedScan = *(std::get<2>(*funcAndClass));
                // (*funcAndClass->first)(m, *funcAndClass->second);
                (*cbFunc)(m);

                auto abcFunc = std::make_shared<AbcFunction>();
                FillFunctionInfo(abcFunc.get(), m, abcClass.get(), nullptr);
                if (ShouldProcessMethod(abcFunc->funcName, processedScan))
                {
                    std::cout << "找到函数: " << abcFunc->funcName << std::endl;
                    abcClass->funcList.push_back(abcFunc);
                }
                return true; });
        module->classList.push_back(abcClass);
    };

    std::function<void(AbckitCoreNamespace *)> cbNamespace = [&](AbckitCoreNamespace *n)
    {
        g_implI->namespaceEnumerateNamespaces(
            n, &cbNamespace, [](AbckitCoreNamespace *n, void *cb)
            {
                (*reinterpret_cast<std::function<void(AbckitCoreNamespace*)>*>(cb))(n);
                return true; });
        g_implI->namespaceEnumerateClasses(n, &cbClass, [](AbckitCoreClass *c, void *cb)
                                           {
            (*reinterpret_cast<std::function<void(AbckitCoreClass*)>*>(cb))(c);
            return true; });
        g_implI->namespaceEnumerateTopLevelFunctions(n, &cbFunc,
                                                     [](AbckitCoreFunction *f, void *cb)
                                                     {
                                                         (*reinterpret_cast<CB *>(cb))(f);
                                                         return true;
                                                     });
    };

    EnumerateAllMethodsInModule(file, cbNamespace, cbClass, cbFunc, processedScan);
}

std::string GetMethodName(AbckitCoreFunction *method)
{
    auto mname = g_implI->functionGetName(method);
    std::string fullSig = g_implI->abckitStringToString(mname);
    auto fullName = fullSig.substr(0, fullSig.find(':'));
    return fullName;
}

void PrintDetailedAbcFileInfo()
{
    std::cout << "\n=================== ABC文件详细信息 ===================" << std::endl;

    if (!g_abcFile || !g_abcFile->file)
    {
        std::cout << "ABC文件未初始化或为空" << std::endl;
        return;
    }

    std::cout << "文件指针: " << g_abcFile->file << std::endl;
    std::cout << "模块数量: " << g_abcFile->moduleList.size() << std::endl;

    for (size_t moduleIdx = 0; moduleIdx < g_abcFile->moduleList.size(); ++moduleIdx)
    {
        auto &module = g_abcFile->moduleList[moduleIdx];
        std::cout << "\n-------------------- 模块 #" << moduleIdx << " --------------------" << std::endl;
        std::cout << "模块名称: \"" << module->entityInfo.moduleName << "\"" << std::endl;
        std::cout << "path: \"" << module->entityInfo.path << "\"" << std::endl;
        std::cout << "Abckit模块指针: " << module->module << std::endl;
        std::cout << "类数量: " << module->classList.size() << std::endl;
        std::cout << "函数数量: " << module->funcList.size() << std::endl;

        // 打印模块级函数信息
        for (size_t funcIdx = 0; funcIdx < module->funcList.size(); ++funcIdx)
        {
            auto &func = module->funcList[funcIdx];
            std::cout << "\n  [模块函数 #" << funcIdx << "]" << std::endl;
            std::cout << "    函数名: \"" << func->funcName << "\"" << std::endl;
            std::cout << "    是否匿名: " << (func->isAnonymous ? "是" : "否") << std::endl;
            std::cout << "    父函数名: \"" << func->entityInfo.parentFuncName << "\"" << std::endl;
            std::cout << "    命名空间: \"" << func->entityInfo.parentNamespaceName << "\"" << std::endl;
            std::cout << "    所属模块: \"" << func->entityInfo.moduleName << "\"" << std::endl;
            std::cout << "    Abckit函数指针: " << func->func << std::endl;
            std::cout << "    path: \"" << func->entityInfo.path << "\"" << std::endl;
        }

        // 打印类信息
        for (size_t classIdx = 0; classIdx < module->classList.size(); ++classIdx)
        {
            auto &cls = module->classList[classIdx];
            std::cout << "\n  ****************** 类 #" << classIdx << " ******************" << std::endl;
            std::cout << "    类名: \"" << cls->entityInfo.className << "\"" << std::endl;
            std::cout << "    命名空间: \"" << cls->entityInfo.parentNamespaceName << "\"" << std::endl;
            std::cout << "    所属模块: \"" << cls->entityInfo.moduleName << "\"" << std::endl;
            std::cout << "    Abckit类指针: " << cls->cls << std::endl;
            std::cout << "    方法数量: " << cls->funcList.size() << std::endl;
            std::cout << "    path: \"" << cls->entityInfo.path << "\"" << std::endl;

            // 打印类方法信息
            for (size_t funcIdx = 0; funcIdx < cls->funcList.size(); ++funcIdx)
            {
                auto &func = cls->funcList[funcIdx];
                std::cout << "\n    [类方法 #" << funcIdx << "]" << std::endl;
                std::cout << "      函数名: \"" << func->funcName << "\"" << std::endl;
                std::cout << "      是否匿名: " << (func->isAnonymous ? "是" : "否") << std::endl;
                std::cout << "      父函数名: \"" << func->entityInfo.parentFuncName << "\"" << std::endl;
                std::cout << "      命名空间: \"" << func->entityInfo.parentNamespaceName << "\"" << std::endl;
                std::cout << "      所属类: \"" << func->entityInfo.className << "\"" << std::endl;
                std::cout << "      所属模块: \"" << func->entityInfo.moduleName << "\"" << std::endl;
                std::cout << "      path: \"" << func->entityInfo.path << "\"" << std::endl;
                std::cout << "      Abckit函数指针: " << func->func << std::endl;
            }
        }
    }

    std::cout << "\n=======================================================" << std::endl;
}

// struct ProcessedScanConfig
// {
//     std::vector<std::string> modules;     // 模块名，支持通配符如 "entry|common|*"
//     std::string normalizedPath;           // 路径，可以是 "src/main/ets/pages/*" 或 "src.main.ets.pages" 格式
//     std::vector<std::string> classNames;  // 类名，支持通配符如 "xxx|yyy"
//     std::vector<std::string> methodNames; // 方法名，支持通配符如 "xxx|yyy"
// };

void PrintProcessedScanConfig(const std::shared_ptr<ProcessedScanConfig> &config)
{
    std::cout << "\n=================== 处理后的扫描配置 ===================" << std::endl;

    // 打印模块数组
    std::cout << "模块列表: [";
    for (size_t i = 0; i < config->modules.size(); ++i)
    {
        std::cout << "\"" << config->modules[i] << "\"";
        if (i < config->modules.size() - 1)
        {
            std::cout << ", ";
        }
    }
    std::cout << "]" << std::endl;

    // 打印标准化路径
    std::cout << "标准化路径: \"" << config->normalizedPath << "\"" << std::endl;

    // 打印类名数组
    std::cout << "类名列表: [";
    for (size_t i = 0; i < config->classNames.size(); ++i)
    {
        std::cout << "\"" << config->classNames[i] << "\"";
        if (i < config->classNames.size() - 1)
        {
            std::cout << ", ";
        }
    }
    std::cout << "]" << std::endl;

    // 打印方法名数组
    std::cout << "方法名列表: [";
    for (size_t i = 0; i < config->methodNames.size(); ++i)
    {
        std::cout << "\"" << config->methodNames[i] << "\"";
        if (i < config->methodNames.size() - 1)
        {
            std::cout << ", ";
        }
    }
    std::cout << "]" << std::endl;

    std::cout << "=======================================================" << std::endl;
}

std::shared_ptr<AbcFile> ProcessAbcFile(const ScanConfig &scanConfig)
{
    g_abcFile->moduleList.clear();
    g_abcFile->file = nullptr;
    // 处理扫描配置
    std::shared_ptr<ProcessedScanConfig> processedScan = ScanConfigProcessor::processScanConfig(scanConfig);
    PrintProcessedScanConfig(processedScan);

    cout << "开始执行插桩操作.." << endl;

    // 1. 读取ABC文件
    AbckitFile *file = g_impl->openAbc(abcPath.data(), strlen(abcPath.data()));
    if (!file)
    {
        std::cerr << "无法打开文件: " << abcPath << std::endl;
        return nullptr;
    }

    // 2. 收集所有的class和方法
    int methodCount = 0;
    EnumerateAllMethods(file, [&](AbckitCoreFunction *method)
                        {
        std::cout << "方法名: " << GetMethodName(method) << std::endl;
        methodCount++; }, processedScan);

    std::cout << "总共收集到 " << methodCount << " 个方法" << std::endl;

    // 3. 打印详细信息
    PrintDetailedAbcFileInfo();

    // 4. 写入输出文件
    if (!outAbcPath.empty())
    {
        g_impl->writeAbc(file, outAbcPath.data(), strlen(outAbcPath.data()));
    }

    // 5. 关闭文件
    g_impl->closeFile(file);

    // 6. 返回处理后的文件信息
    return g_abcFile;
}
int main()
{

    ScanConfig scan("library|entry", "src/main/", "Index|Component", "onCreate|aboutToAppear");
    ScanConfig scan1;

    // 使用封装的函数处理ABC文件
    auto result = ProcessAbcFile(scan1);
    if (result)
    {
        std::cout << "处理成功!" << std::endl;
    }
    else
    {
        std::cout << "处理失败!" << std::endl;
    }
    return 0;
}

/*
scan{
moduke:"entry|common| xxx",
path:"src/main/ets/pages/*", or "src.main.ets.pages"
className: "xxx | yyy ",
methName: "xxx | yyy "
}
*/
